package thread;

import java.util.concurrent.PriorityBlockingQueue;

/**
 * Created with IntelliJ IDEA.
 * ClassName: TimeDemo
 * Package: thread
 * Description:
 * User: fzykd
 *
 * @Author: LQH
 * Date: 2023-10-10
 * Time: 18:31
 */

//创建一个表示定时器中的一个任务
class MyTask implements Comparable<MyTask> {
    //具体任务
    private Runnable runnable;
    //任务什么时候执行
    private long time;

    //构造方法
    public MyTask(Runnable runnable, long after) {
        this.runnable = runnable;
        //传来的时间是 一个相对时间
        this.time = System.currentTimeMillis() + after;
    }

    public long getTime() {
        return time;
    }

    public void run() {
        runnable.run();
    }

    //比较时间的方法
    @Override
    public int compareTo(MyTask o) {
        return (int) (this.time = o.time);
    }
}

//创建一个类 表示定时器
class MyTimer {
    //组织 布置 创建任务

    //定时器中存放多个任务 线程安全的阻塞队列 内部是堆实现的 堆的排序要明确 按照时间大小来排序
    private PriorityBlockingQueue<MyTask> queue = new PriorityBlockingQueue<MyTask>();

    //设置一个锁对象
    private Object object = new Object();

    //定时器中布置任务的方法
    public void schedule(Runnable runnable, long delay) {
        MyTask task = new MyTask(runnable, delay);
        queue.put(task);
        //有新的任务进来 去唤醒等待
        synchronized (object){
            object.notify();
        }
    }

    //构造方法
    public MyTimer() {
        Thread t = new Thread(() -> {
            //不停的检查
            while (true) {
                //取出队列首元素
                try {
                    MyTask task = queue.take();
                    //获取当前系统时间
                    long curTime = System.currentTimeMillis();
                    //判断时间是否要到了
                    if (curTime < task.getTime()) {
                        //说明时间没到 再放回队列中去
                        queue.put(task);

                        //时间没到 设置一个等待时间
                        synchronized (object) {
                            object.wait(task.getTime() - curTime);
                        }

                    } else {
                        //时间到了 执行任务
                        task.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });

        t.start();
    }

}


//定时器
public class TimeDemo {
    public static void main(String[] args) {
        MyTimer myTimer = new MyTimer();
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("定时器");
            }
        },3000);

        System.out.println("main");
    }
}
